package com.moliku.insurance.common.response;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.moliku.insurance.common.constant.InsureStatusEnum;
import com.moliku.insurance.common.exception.CancelPolicyException;
import com.moliku.insurance.common.exception.DownloadPolicyException;
import com.moliku.insurance.common.exception.SubmitPolicyException;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.Serializable;
import java.util.Arrays;

/**
 * 通用投保|退保统一响应
 *
 * @author Mr.Liu
 * @since 2021/3/20
 */
@SuppressWarnings("unused")
public class CommonInsureResult implements Serializable {
    private static final long serialVersionUID = -2935773960269526629L;
    /**
     * 投保|退保 结果
     */
    @Getter
    private InsureStatusEnum status;
    /**
     * 投保成功后的保单号
     */
    private String policyNo;
    /**
     * 下载保单数据 byte 流
     */
    private byte[] downloadPolicyBytes;

    /**
     * 自定义消息
     */
    private String message;

    private CommonInsureResult() {
    }

    public CommonInsureResult(InsureStatusEnum status) {
        this.status = status;
    }

    public CommonInsureResult(InsureStatusEnum status, String message) {
        this.status = status;
        this.message = message;
    }

    /**
     * 投保成功
     *
     * @param policyNo 保单号
     * @return 投保结果
     */
    public static CommonInsureResult submitPolicySuccess(String policyNo) {
        CommonInsureResult result = new CommonInsureResult(InsureStatusEnum.INSURE_SUCCESS);
        result.policyNo = policyNo;
        return result;
    }

    /**
     * 投保失败
     *
     * @return 投保结果
     */
    public static CommonInsureResult submitPolicyFail() {
        return new CommonInsureResult(InsureStatusEnum.INSURE_FAIL);
    }

    /**
     * 投保失败
     *
     * @param status 投保失败状态信息
     * @return 投保结果
     */
    public static CommonInsureResult submitPolicyFail(InsureStatusEnum status) {
        return new CommonInsureResult(status);
    }

    /**
     * 投保失败
     *
     * @param message 自定义投保失败消息
     * @return 投保结果
     */
    public static CommonInsureResult submitPolicyFail(String message) {
        return new CommonInsureResult(InsureStatusEnum.INSURE_FAIL, message);
    }

    /**
     * 投保失败
     *
     * @param exception 自定义投保失败异常
     * @return 投保结果
     */
    public static CommonInsureResult submitPolicyFail(SubmitPolicyException exception) {
        return new CommonInsureResult(exception.getInsureStatus(), exception.getMessage());
    }


    /**
     * 退保成功
     *
     * @return 退保结果
     */
    public static CommonInsureResult cancelPolicySuccess() {
        return new CommonInsureResult(InsureStatusEnum.CANCEL_INSURE_SUCCESS);
    }


    /**
     * 退保失败
     *
     * @return 退保结果
     */
    public static CommonInsureResult cancelPolicyFail() {
        return new CommonInsureResult(InsureStatusEnum.CANCEL_INSURE_FAIL);
    }

    /**
     * 退保失败
     *
     * @param exception 自定义失败异常
     * @return 退保结果
     */
    public static CommonInsureResult cancelPolicyFail(CancelPolicyException exception) {
        return new CommonInsureResult(exception.getInsureStatus(), exception.getMessage());
    }

    /**
     * 退保失败
     *
     * @param status 退保失败状态信息
     * @return 退保结果
     */
    public static CommonInsureResult cancelPolicyFail(InsureStatusEnum status) {
        return new CommonInsureResult(status);
    }

    /**
     * 退保失败
     *
     * @param message 自定义退保失败提示消息
     * @return 退保结果
     */
    public static CommonInsureResult cancelPolicyFail(String message) {
        return new CommonInsureResult(InsureStatusEnum.CANCEL_INSURE_FAIL, message);
    }


    /**
     * 下载保单成功
     *
     * @param data 保单数据流
     * @return 下载结果
     */
    public static CommonInsureResult downloadPolicySuccess(byte[] data) {
        CommonInsureResult result = new CommonInsureResult(InsureStatusEnum.DOWNLOAD_INSURE_SUCCESS);
        result.downloadPolicyBytes = data;
        return result;
    }

    /**
     * 下载保单失败
     *
     * @return 下载结果
     */
    public static CommonInsureResult downloadPolicyFail() {
        return new CommonInsureResult(InsureStatusEnum.DOWNLOAD_INSURE_FAIL);
    }

    /**
     * 下载保单失败
     *
     * @return 下载结果
     */
    public static CommonInsureResult downloadPolicyFail(DownloadPolicyException exception) {
        return new CommonInsureResult(exception.getInsureStatus(), exception.getMessage());
    }

    /**
     * 下载保单失败
     *
     * @return 下载结果
     */
    public static CommonInsureResult downloadPolicyFail(InsureStatusEnum status) {
        return new CommonInsureResult(status);
    }

    /**
     * 下载保单失败
     *
     * @param message 自定义失败消息
     * @return 下载结果
     */
    public static CommonInsureResult downloadPolicyFail(String message) {
        return new CommonInsureResult(InsureStatusEnum.DOWNLOAD_INSURE_FAIL, message);
    }


    /**
     * 投保结果封装
     *
     * @return 投保结果
     */
    public SubmitPolicyResult getSubmitPolicyResult() {
        return new SubmitPolicyResult(status.getCode(), getMsg(), policyNo);
    }

    /**
     * 退保结果封装
     *
     * @return 退保结果
     */
    public CancelPolicyResult getCancelPolicyResult() {
        return new CancelPolicyResult(status.getCode(), getMsg());
    }

    /**
     * 下载保单结果封装
     *
     * @return 退保结果
     */
    public DownloadPolicyResult getDownloadPolicyResult() {
        String fileData = ArrayUtils.isNotEmpty(downloadPolicyBytes) ? Arrays.toString(downloadPolicyBytes) : null;
        return new DownloadPolicyResult(status.getCode(), getMsg(), fileData);
    }

    /**
     * 获取最终的消息提示
     *
     * @return 消息提示
     */
    private String getMsg() {
        return StringUtils.isNotBlank(message) ? message : status.getMessage();
    }


    @Data
    @AllArgsConstructor
    @JsonInclude(JsonInclude.Include.NON_NULL)
    public static class SubmitPolicyResult {
        private Integer status;
        private String msg;
        private String policyNo;
    }

    @Data
    @AllArgsConstructor
    public static class CancelPolicyResult {
        private Integer status;
        private String msg;
    }

    @Data
    @AllArgsConstructor
    @JsonInclude(JsonInclude.Include.NON_NULL)
    public static class DownloadPolicyResult {
        private Integer status;
        private String msg;
        private String file;
    }
}
